# -*- coding: utf-8 -*-
"""
    xfree.forum.locals
    ~~~~~~~~~~~~~~~~~~~~~
    文件描述：xfree的线程本地辅助函数
    作者：xfree
    邮箱：cy_83k@qq.com
"""

from flask import g, has_request_context, request
from werkzeug.local import LocalProxy

from .models import Category, Forum, Post, Topic


@LocalProxy
def current_post():
    """
    获取当前帖子的代理函数。

    它通过调用_get_item函数，尝试从请求参数中获取帖子对象，并将其存储在g对象中（如果尚未存储），然后返回该帖子对象。
    """
    return _get_item(Post, "post_id", "post")


@LocalProxy
def current_topic():
    """
    获取当前主题的代理函数。

    如果当前存在帖子（通过current_post获取），则返回该帖子所属的主题；否则，通过调用_get_item函数，尝试从请求参数中获取主题对象，并将其存储在g对象中（如果尚未存储），然后返回该主题对象。
    """
    if current_post:
        return current_post.topic
    return _get_item(Topic, "topic_id", "topic")


@LocalProxy
def current_forum():
    """
    获取当前论坛的代理函数。

    如果当前存在主题（通过current_topic获取），则返回该主题所属的论坛；否则，通过调用_get_item函数，尝试从请求参数中获取论坛对象，并将其存储在g对象中（如果尚未存储），然后返回该论坛对象。
    """
    if current_topic:
        return current_topic.forum
    return _get_item(Forum, "forum_id", "forum")


@LocalProxy
def current_category():
    """
    获取当前分类的代理函数。

    如果当前存在论坛（通过current_forum获取），则返回该论坛所属的分类；否则，通过调用_get_item函数，尝试从请求参数中获取分类对象，并将其存储在g对象中（如果尚未存储），然后返回该分类对象。
    """
    if current_forum:
        return current_forum.category
    return _get_item(Category, "category_id", "category")


def _get_item(model, view_arg, name):
    """
    根据给定的模型、视图参数和名称，从请求参数中获取对象并存储在g对象中的函数。

    :param model: 数据库模型类（如Post、Topic等）
    :param view_arg: 请求视图参数中的键（如"post_id"、"topic_id"等）
    :param name: 用于在g对象中存储对象的属性名
    :return: 从g对象中获取的对象（如果存在），否则为None
    """
    if (
        has_request_context()
        and not getattr(g, name, None)
        and view_arg in request.view_args
    ):
        setattr(
            g,
            name,
            model.query.filter_by(id=request.view_args[view_arg]).first(),
        )

    return getattr(g, name, None)